#include <iostream>
#include <string>
#include <vector>

#include <algorithm>
#include <memory>
#include <functional>

class SizeCompare {
private:
    size_t sz;

public:
    SizeCompare(size_t n) : sz(n) {}

public:
    // const 成员函数, 重载函数调用操作符
    bool operator()(const std::string& s) const {
        return s.size() >= sz;
    }
};


class A{
    int& a;

public:
    A(int& a) : a(a) {}

    void aplusplus() const { a++; } //const 成员函数修改引用类型成员
};


bool isShorter(const std::string& s, int sz) {
    return s.size() >= sz;
}

int main() {
    size_t sz = 0;

    //按值捕获
    auto sizeComp = [sz](const std::string& s){
        return s.size() >= sz;
    };
    std::cout << "sizeComp: " << sizeComp("hello") << std::endl;
    std::cout << "size of sizeComp: " << sizeof(sizeComp) << std::endl;

    SizeCompare sizeCompare(sz);
    std::cout << "SizeCompare: " << sizeCompare("world") << std::endl;
    std::cout << "size of SizeCompare: " << sizeof(SizeCompare) << std::endl;
    
    int a1 = 0;
    A a(a1);
    a.aplusplus();  //a1 = 1


    int i = 0;
    auto simpleLambda = [i]() {
        std::cout << i << std::endl;
    };
    
    i = 10;
    simpleLambda(); // 0

    auto important = std::make_unique<int>(100);
    auto importantLambda = [important = std::move(important)] {
        std::cout << *important << std::endl;
    };
    importantLambda();
    
    std::vector<std::string> vs = {
        "Hello", "world", "!"
    };

    //std::find_if
    sz = 5;
    auto iter = std::find_if(vs.begin(), vs.end(), [sz](const std::string& s) {
        return s.size() >= sz;
    });

    std::cout << ((iter == vs.end()) ? "" : *iter) << std::endl;

    //std::bind
    auto binder = std::bind(isShorter, std::placeholders::_1, sz);
    auto iter1 = std::find_if(vs.begin(), vs.end(), [sz](const std::string& s) {
        return s.size() >= sz;
    });

    std::cout << ((iter == vs.end()) ? "" : *iter) << std::endl;

    //std::function
    auto lamb = [sz](const std::string& s) {
        return s.size() >= sz;
    };
    std::vector<std::function<bool(const std::string&)>> funcs = {
        binder, lamb
    };

    for (auto func : funcs) {
        std::cout << func("hello") << std::endl;
    }

    //lambda 无捕获时, 是一个函数指针
    void(*funcptr)(int) = [](int i){
        std::cout << "do nothing funcptr" << std::endl;
    };
    funcptr(0);

    return 0;
}